package com.huawei.codearts.tools.ratelimit.service;

import com.huawei.codearts.dao.RedisDao;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Component
public class RedisLuaLimiter {

    private static final Logger logger = LoggerFactory.getLogger(RedisLuaLimiter.class);

    private final RedisDao redisDao;
    private int limitTime = 1;  // 时间窗口，单位秒
    private int requestLimit = 10;  // 每个时间窗口内允许的请求数

    public RedisLuaLimiter(RedisDao redisDao) {
        this.redisDao = redisDao;
    }

    public boolean tryAcquire(String requestKey) {
        return acquireLimiter(requestKey);
    }

    public boolean tryAcquire(String requestKey, int limitTime, int requestLimit) {
        setLimitTime(limitTime);
        setRequestLimit(requestLimit);
        return acquireLimiter(requestKey);
    }

    public boolean acquireLimiter(String requestKey) {
        String combineKey = "rate_limit:" + requestKey;

        Long currentCount = redisDao.rateLimiter(combineKey, limitTime, requestLimit);

        // 检查是否超过限流
        if (currentCount == null || currentCount.intValue() > requestLimit) {
            logger.info("当前接口以达到最大限流次数, key={}", combineKey);
            return true;
        }
        logger.info("一个时间窗内请求次数：{}，当前请求次数：{}，缓存的 key 为 {}", requestLimit, currentCount, combineKey);
        return false;
    }

    public RedisLuaLimiter setLimitTime(int limitTime) {
        this.limitTime = limitTime;
        return this;
    }

    public RedisLuaLimiter setRequestLimit(int requestLimit) {
        this.requestLimit = requestLimit;
        return this;
    }

    // 使用SETNX命令实现幂等性检查
    public boolean isDuplicateRequest(String requestKey) {
        String redisKey = "request_limit:" + requestKey;
        String isFirstRequest = redisDao.setIfAbsent(redisKey, "1", limitTime);
        return isFirstRequest == null || !isFirstRequest.equalsIgnoreCase("OK");
    }

}
